home *** CD-ROM | disk | FTP | other *** search
- /*
- * MandelVroom 2.0
- *
- * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
- *
- * All rights reserved.
- *
- * Permission is hereby granted to distribute this program's source
- * executable, and documentation for non-comercial purposes, so long as the
- * copyright notices are not removed from the sources, executable or
- * documentation. This program may not be distributed for a profit without
- * the express written consent of the author Kevin L. Clague.
- *
- * This program is not in the public domain.
- *
- * Fred Fish is expressly granted permission to distribute this program's
- * source and executable as part of the "Fred Fish freely redistributable
- * Amiga software library."
- *
- * Permission is expressly granted for this program and it's source to be
- * distributed as part of the Amicus Amiga software disks, and the
- * First Amiga User Group's Hot Mix disks.
- *
- * contents: this file contains funtions to create, maintain and delete
- * Mandelbrot and Julia projects (including spawning off child generator
- * tasks.)
- */
-
- #include "mandp.h"
-
- struct NewWindow NewMand = {
- 0,12, /* start position */
- 80,80, /* width, height */
-
- (UBYTE) 0, (UBYTE) NORMALPEN,
- NULL, /* IDCMP flags */
- /* MandWind flags */
- WINDOWCLOSE | WINDOWDEPTH | WINDOWSIZING | WINDOWDRAG | ACTIVATE |
- REPORTMOUSE | NOCAREREFRESH | SMART_REFRESH,
- (struct Gadget *) NULL, /* first gadget */
- (struct Image *) NULL, /* user checkmark */
- (UBYTE *) NULL, /* Title */
- (struct Screen *) NULL, /* pointer to screen */
- (struct BitMap *) NULL, /* pointer to superbitmap */
- 20,20,-1,-1, /* sizing */
- CUSTOMSCREEN /* type of screen */
- };
-
- LONG TopMarg = 10;
- LONG BotMarg = 2;
- LONG LeftMarg = 2;
- LONG RightMarg;
-
- ULONG CalcTime;
-
- extern LONG TaskPri, MainPri;
- extern LONG pSigMask;
-
- extern struct ExecBase *ExecBase;
-
- static struct Picture *GenNPict;
-
- /* Toggle generation of project */
-
- GenerateCmd(Msg)
- struct IntuiMessage *Msg;
- {
- switch(Msg->Class) {
-
- case GADGETDOWN:
- ToggleGen((struct Picture *) Msg->IDCMPWindow->UserData);
- break;
-
- case MENUPICK:
- switch( SUBNUM(Msg->Code) ) {
- case STARTGEN:
-
- CurPict->GenState = GENPENDSTATE;
- Generate( CurPict );
- break;
-
- case STOPGEN:
-
- ThrowTask(CurPict);
- break;
-
- case CONTGEN:
-
- CurPict->GenState = CONTINUESTATE;
- Generate( CurPict );
- break;
- }
- break;
- }
- }
-
- ToggleGen( Pict )
- struct Picture *Pict;
- {
- if ( Pict->gTask ) {
-
- ThrowTask( Pict );
- } else {
-
- Pict->GenState = GENPENDSTATE;
- Generate( Pict );
- }
- SetGenGad( Pict );
- }
-
- /*
- * Generate It
- */
- Generate( Pict )
- register struct Picture *Pict;
- {
-
- register char *t;
-
- int GenTask();
-
- extern struct MenuItem LensSub[];
-
- if ( Pict->gTask ) {
- return;
- }
-
- if (Pict->Flags & SCROLL_HAPPENED) {
-
- /* create a new counts array with unclipped data in it */
- /* adjust the real and imaginary upper left */
-
- ScrollComplex(Pict);
-
- if (Pict->Counts == NULL)
- return;
-
- } else {
-
- FreeScrollTemp(Pict);
-
- if (Pict->GenState == CONTINUESTATE ){
- if ( Pict->CurLine < Pict->CountY ) {
- if (Pict->Counts == NULL) return;
- } else {
- return;
- }
- }
-
- if (Pict->GenState == GENPENDSTATE) {
-
- InitNewGen( Pict );
- if (Pict->Counts == NULL) return;
- }
- }
- ResetScrollRects(Pict);
-
- Pict->GenState = GENERATESTATE;
-
- if ( Pict->MathMode == INTIIGENERATOR &&
- (ExecBase->AttnFlags & (1 << AFB_68020)) == 0 ) {
-
- Pict->MathMode = INTGENERATOR;
- }
-
- if ( Pict->MathMode == _81GENERATOR &&
- (ExecBase->AttnFlags & (1 << AFB_68881)) == 0 ) {
-
- Pict->MathMode = IEEEGENERATOR;
- }
-
- MakeColorXlate( Pict );
-
- if (Pict->MathMode == 1) {
-
- if (OpenFFPLibs() != 0)
- return;
- }
-
- /* Spawn off the generator as a task */
-
- DateStamp( Pict->TimeStamp );
-
- /* GenNPict is pointer to Picture that task needs to generate */
-
- GenNPict = Pict;
-
- #define KAY (1024L)
-
- #ifdef MULTI
- Pict->gTask = CreateTask( Pict->Title+2, MainPri, GenTask, KAY);
-
- if ( Pict->gTask == NULL ) {
- DispErrMsg("Could not create task",0);
- }
-
- SetGenGad( Pict );
-
- /* Do this so we are sure child is done with GenNPict */
-
- Wait( pSigMask );
-
- #else
- GenTask();
- #endif
- }
-
- InitNewGen( Pict )
- register struct Picture *Pict;
- {
-
- if (Pict->Flags & BORDERLESS_PROJ) {
-
- Pict->LeftMarg = 0;
- Pict->RightMarg = 0;
- Pict->TopMarg = 0;
- Pict->BotMarg = 0;
- }
-
- /* figure out new picture size */
-
- Pict->CountX = Pict->Window->Width-(Pict->LeftMarg+Pict->RightMarg);
- Pict->CountY = Pict->Window->Height-(Pict->TopMarg+Pict->BotMarg);
-
- /* free up old counts memory, get new picture size, get new counts memory
- */
-
- GetCountsMemory( Pict );
-
- if (Pict->Counts == NULL) {
- DispErrMsg("Can't generate. Out of RAM!!",0);
- return;
- }
-
- if (Pict->Flags & NO_RAM_GENERATE ) {
- DispErrMsg("Can't save counts. Out of RAM!!",0);
- }
-
- /* calculate new picture's coordinates from zoom box */
-
- ZoomIn( Pict );
- Pict->CurLine = 0;
-
- /* clear the picture area */
-
- if (!(Pict->Flags & LENS_DISPLAYED)) {
-
- SetAPen( Pict->Window->RPort, NORMALPEN );
- RectFill( Pict->Window->RPort, Pict->LeftMarg, Pict->TopMarg,
- Pict->Window->Width - Pict->RightMarg - 1,
- Pict->Window->Height - Pict->BotMarg - 1);
- }
- }
-
- GenTask() {
-
- register struct Picture *Pict;
-
- int MandelbrotInt32();
- int MandelbrotInt32II();
- int MandelbrotIEEE();
- int MandelbrotFFP();
-
- int JuliaInt32();
- int JuliaIEEE();
- int JuliaFFP();
-
- LONG SPFieee();
-
- #ifdef MULTI
- geta4();
- #endif
-
- Pict = GenNPict;
-
- /* Signal Parent that we have accessed GenNPict */
-
- Signal( mTask, pSigMask );
-
- /* Lower our priority while we generate */
-
- SetTaskPri( FindTask(0), TaskPri );
-
- Pict->GenChildState = GENINCOMPLETE;
-
- if (GetTaskSig( Pict ) == UNSUCCESSFUL) {
- Pict->GenChildState = NOSIGSTATE;
-
- } else {
- Pict->GenChildState = GENINCOMPLETE;
-
- if ( Pict->pNode.ln_Type == MANDPICT ) {
-
- switch ( Pict->MathMode ) {
- case 0:
- MandelbrotInt32( Pict );
- break;
-
- case 2:
- case 4:
- MandelbrotIEEE( Pict );
- break;
-
- case 3:
- MandelbrotInt32II( Pict );
- break;
-
- case 1: {
- /*
- * Constraints for IEEE to FFP conversion
- *
- * 1. SPFieee() expects 32 bit IEEE floats
- * 2. The C language always promotes floats to doubles for
- * parameter passing.
- * 3. doubles are 64 bits wide
- *
- * Therefore I must do the following:
- *
- * 1. Convert double parameters to float
- * 2. Take the address of the floats and cast them to *ULONG
- * 3. Indirect off the ULONG pointers that are pointing to
- * 32 IEEE format floats (gross eh?) as parameters to FFP
- * Mandelbrot function.
- */
-
- /* 32 bit IEEE float variables */
-
- float StartX_float, StartY_float, GapX_float, GapY_float;
-
- /* convert 64 bit IEEE variables into 32 bit IEEE variables */
-
- StartX_float = Pict->RealLow;
- StartY_float = Pict->ImagLow + Pict->CurLine*Pict->RealGap;
- GapX_float = Pict->RealGap;
- GapY_float = Pict->ImagGap;
-
- /*
- * calculate pointers and convert them to pointers to ULONG
- * so that when we indirect off of these and pass the results
- * as parameters they are not promoted to doubles.
- */
-
-
- MandelbrotFFP( Pict,
- *( (ULONG *) &StartX_float ),
- *( (ULONG *) &StartY_float ),
- *( (ULONG *) &GapX_float ),
- *( (ULONG *) &GapY_float ));
- }
- break;
- }
- } else {
-
- switch ( Pict->MathMode ) {
-
- case 0:
- case 3:
- JuliaInt32( Pict );
- break;
-
- case 2:
- case 4:
- JuliaIEEE( Pict );
- break;
-
- case 1: {
- /*
- * Constraints for IEEE to FFP conversion
- *
- * 1. SPFieee() expects 32 bit IEEE float
- * 2. The C language always promotes floats to doubles for
- * parameter passing.
- * 3. doubles are 64 bits wide
- *
- * Therefore I must do the following:
- *
- * 1. Convert double parameters to float
- * 2. Take the address of the floats and cast them to *ULONG
- * 3. Indirect off the ULONG pointers that are pointing to
- * 32 IEEE format floats (gross eh?) as parameters to FFP
- * Julia function.
- */
-
- /* 32 bit IEEE float variables */
-
- float JuliaX_float, JuliaY_float;
- float StartX, StartY, GapX, GapY;
-
- /* convert 64 bit IEEE variables into 32 bit IEEE variables */
-
- JuliaX_float = Pict->Real;
- JuliaY_float = Pict->Imag;
- StartX = Pict->RealLow;
- StartY = Pict->ImagLow;
- GapX = Pict->RealGap;
- GapY = Pict->ImagGap;
-
- /*
- * calculate pointers and convert them to pointers to ULONG
- * so that when we indirect off of these and pass the results
- * as parameters they are not promoted to doubles.
- */
-
- JuliaFFP( Pict, *( (ULONG *) &JuliaX_float ),
- *( (ULONG *) &JuliaY_float ),
- *( (ULONG *) &StartX ),
- *( (ULONG *) &StartY ),
- *( (ULONG *) &GapX ),
- *( (ULONG *) &GapY ) );
- }
- break;
- }
- }
- Pict->GenChildState = GENCOMPLETE;
- }
-
- #ifdef MULTI
-
- /* Indicate that generation has finished for this task */
-
- Signal( mTask, mSigMask ); /* signal parent as to change */
-
- while (Pict->GenState != KILLSTATE) { /* Wait for task to be removed */
-
- while (Pict->GenState == GENERATESTATE) { /* spin 'till parent kills us */
- }
-
- /* accept any pauses that the parent may send too late */
-
- if (Pict->GenState == PAUSESTATE) {
- ChildSignal(Pict); /* signal back so parent doesn't hang */
- }
- }
-
- /* We've been informed that we will die, so free up resources */
-
- FreeSignal( Pict->gSigBit );
- Signal( mTask, pSigMask ); /* signal death O.K. */
- Wait( 0L ); /* stop here forever */
- #endif
- }
-
- InitMand( Pict )
- register struct Picture *Pict;
- {
-
- Pict->Real = 0.0;
- Pict->Imag = 0.0;
- }
-
- SetWindowActive( Window, Active )
- register struct Window *Window;
- char Active;
- {
- struct Picture *Pict;
-
- if ( Window ) {
-
- Pict = (struct Picture *) Window->UserData;
-
- if ( ! (Pict->Flags & BORDERLESS_PROJ)) {
- Window->Title[0] = Active;
- SetWindowTitles( Window, Window->Title, -1 );
- }
- }
- }
-
- /*
- * Free up old memory and get memory for new picture
- */
- GetCountsMemory( Pict )
- register struct Picture *Pict;
- {
- /* free up old pictures iteration count pile */
-
- FreeCounts( Pict );
-
- /* Allocate memory for new picture */
-
- Pict->CountsSize = Pict->CountX * Pict->CountY * sizeof(SHORT);
- Pict->Counts = (SHORT *) safeAllocMem(Pict->CountsSize, MEMF_CLEAR );
-
- if (Pict->Counts == NULL) {
-
- Pict->CountsSize = Pict->CountX * sizeof(SHORT);
- Pict->Counts = (SHORT *) safeAllocMem(Pict->CountsSize, MEMF_CLEAR);
-
- if (Pict->Counts != NULL)
- Pict->Flags |= NO_RAM_GENERATE;
-
- } else {
-
- Pict->Flags &= ~NO_RAM_GENERATE;
- }
- }
-
- FreeCounts( Pict )
- register struct Picture *Pict;
- {
- if ( Pict->Counts ) {
-
- FreeMem( Pict->Counts, Pict->CountsSize );
- Pict->Counts = NULL;
- }
- }
-
- struct Gadget *
- MakePictGads( Type )
- register int Type;
- {
- register struct Gadget *gadget;
- register struct Gadget *Newgadget;
- register struct Gadget *Firstgadget;
- register struct IntuiText *Intui;
- register char *str;
-
- struct Border *Border, *MakeShadow();
-
- register int i,j,k;
-
- struct IntuiText *ShadowIntui();
-
- j = TOPMARG;
-
- if ( Type == MANDPICT ) {
- k = 4;
- } else {
- k = 5;
- }
-
- Firstgadget = NULL;
-
- for (i = 0; i < k; i++) {
-
- Newgadget = MakeBool(-15,j, 12,12, 0,(PICTTYPE<<WINDTYPEBITS)+i,NULL);
-
- if (Newgadget) {
-
- if ( i == 0 ) {
-
- Firstgadget = Newgadget;
-
- } else {
-
- gadget->NextGadget = Newgadget;
- }
-
- Newgadget->Flags |= GRELRIGHT;
- Newgadget->Activation |= RIGHTBORDER;
-
- gadget = Newgadget;
-
- j += 14;
-
- switch( i ) {
- case 0: str = "C"; break;
- case 1: str = "G"; break;
- case 2: str = "I"; break;
- case 3: str = "O"; break;
- case 4: str = "J"; break;
- }
-
- Intui = ShadowIntui( str, 3, 3);
-
- if (Intui == NULL) {
- FreeGadgets( Firstgadget );
- }
-
- gadget->GadgetText = Intui;
-
- #define NUMPATCHCORNERS 5
-
- Border = MakeShadow( NORMALPEN, NUMPATCHCORNERS );
-
- if ( Border ) {
- InitPatch( Border );
- Border->NextBorder = (struct Border *) gadget->GadgetRender;
- gadget->GadgetRender = (APTR) Border;
- }
-
- } else {
-
- if (Firstgadget)
- FreeGadgets( Firstgadget );
-
- return( NULL );
- }
- }
- return( Firstgadget );
- }
-
- SetGenGad( Pict )
- register struct Picture *Pict;
- {
- register struct Window *Window;
- register struct Gadget *Gadget;
- register struct IntuiText *Intui;
- register char c;
- register int place;
-
- if (Pict == NULL)
- return;
-
- if (Pict->Flags & BORDERLESS_PROJ)
- return;
-
- Window = Pict->Window;
-
- if (Window) {
-
- if ( Pict->gTask )
- c = 'S';
- else
- c = 'G';
-
- Gadget = Pict->Gadgets->NextGadget;
-
- place = RemoveGadget( Window, Gadget );
-
- Intui = Gadget->GadgetText;
-
- Intui = Intui->NextText;
- Intui->IText[0] = c;
-
- Intui = Intui->NextText;
- Intui->IText[0] = c;
-
- AddGadget( Window, Gadget, place );
-
- RefreshGadgets( Pict->Gadgets, Window, NULL );
- }
- }
-
- InitPatch( Border )
- register struct Border *Border;
- {
- register SHORT *NewCounts;
-
- NewCounts = Border->XY;
-
- *NewCounts++ = 3; *NewCounts++ = 11;
- *NewCounts++ = 2; *NewCounts++ = 11;
- *NewCounts++ = 2; *NewCounts++ = 2;
- *NewCounts++ = 11; *NewCounts++ = 2;
- *NewCounts++ = 11; *NewCounts++ = 3;
-
- } /* InitPatch */
-
- /*
- * Open the Picture window
- */
- OpenPicture( Pict )
- struct Picture *Pict;
- {
- extern struct Window *OpenMyWind();
-
- register struct Window *Window;
- register struct NewWindow *NewWind;
-
- register LONG width, height;
- register LONG extrax,extray;
-
- struct Gadget *gadgets, *MakePictGads();
-
- if ( Pict->Window == NULL ) {
-
- width = Pict->CountX;
- height = Pict->CountY;
-
- NewWind = Pict->NewWind;
-
- if (Pict->Flags & BORDERLESS_PROJ) {
-
- NewWind->Flags = ACTIVATE | REPORTMOUSE | NOCAREREFRESH |
- SMART_REFRESH | BORDERLESS;
- NewWind->Title = NULL;
- Pict->Gadgets = gadgets = NULL;
-
- if (Pict->LeftEdge+Pict->CountX+LEFTMARG+RIGHTMARG == screen->Width &&
- Pict->TopEdge +Pict->CountY+TOPMARG+BOTMARG == screen->Height) {
-
- Pict->LeftMarg = LEFTMARG;
- Pict->RightMarg = RIGHTMARG;
- Pict->TopMarg = TOPMARG;
- Pict->BotMarg = BOTMARG;
- } else {
-
- Pict->LeftMarg = 0;
- Pict->RightMarg = 0;
- Pict->TopMarg = 0;
- Pict->BotMarg = 0;
- }
- } else {
-
- NewWind->Flags = WINDOWCLOSE | WINDOWDEPTH | WINDOWSIZING |
- WINDOWDRAG | ACTIVATE | REPORTMOUSE | NOCAREREFRESH |
- SMART_REFRESH;
- NewWind->Title = (UBYTE *) Pict->Title;
- Pict->Gadgets = gadgets = MakePictGads( Pict->pNode.ln_Type );
-
- Pict->LeftMarg = LEFTMARG;
- Pict->RightMarg = RIGHTMARG;
- Pict->TopMarg = TOPMARG;
- Pict->BotMarg = BOTMARG;
- }
-
- width += Pict->LeftMarg + Pict->RightMarg;
- height += Pict->TopMarg + Pict->BotMarg;
-
- extrax = width - screen->Width;
- extray = height - screen->Height;
-
- if ( extrax > 0 || extray > 0 ) {
-
- ThrowTask( Pict);
- FreeCounts( Pict);
- DispErrMsg("Picture too big. Regenerate",0);
-
- if ( extrax > 0 ) {
- Pict->CountX -= extrax;
- width -= extrax;
- }
-
- if ( extray > 0 ) {
- Pict->CountY -= extray;
- height -= extray;
- }
- }
-
- NewWind->LeftEdge = Pict->LeftEdge;
- NewWind->TopEdge = Pict->TopEdge;
-
- Window = OpenMyWind(NewWind, screen, gadgets, width, height );
-
- Pict->Window = Window;
-
- if (Window == NULL) {
-
- DispErrMsg("Can't open picture window",0);
- FreeGadgets( Pict->Gadgets );
- ThrowPict(Pict);
- return( -1 );
-
- } else {
-
- CurWind = Window;
- DisplayMsg();
-
- SetAPen( Window->RPort, NORMALPEN );
-
- if (Pict->Flags & BORDERLESS_PROJ) {
- RectFill( Window->RPort, Pict->LeftMarg, Pict->TopMarg,
- NewWind->Width-Pict->RightMarg-1,
- NewWind->Height-Pict->BotMarg-1);
- } else {
- RectFill( Window->RPort, Pict->LeftMarg, Pict->TopMarg,
- NewWind->Width, NewWind->Height);
- }
-
- Window->UserData = (BYTE *) Pict;
-
- MoveResize( Pict->Window, &Pict->SizingGadget );
- BorderWindow( Window );
-
- if (Pict->CycleOn) {
- CreateCycle();
- }
- }
- }
- SetGenGad( Pict );
- return( 0 );
- } /* OpenPicture */
-
- MoveResize( Window, RetGadget )
- register struct Window *Window;
- register struct Gadget **RetGadget;
- {
- register struct Gadget *Gadget;
- register int place;
-
- Gadget = Window->FirstGadget;
-
- while ( Gadget && !(Gadget->GadgetType & SIZING)) {
- Gadget = Gadget->NextGadget;
- }
-
- if (Gadget) {
-
- *RetGadget = Gadget;
-
- place = RemoveGadget( Window, Gadget );
-
- if (XScale == 0)
- Gadget->LeftEdge -= 2;
-
- if (YScale == 0)
- Gadget->TopEdge -= 3;
- else
- Gadget->TopEdge -= 1;
-
- AddGadget( Window, Gadget, place );
-
- RefreshGList( Gadget, Window, NULL, 1);
- }
- }
-
- /*
- * Close the Mandelbrot Window
- */
- ClosePicture( Pict )
- register struct Picture *Pict;
- {
- register struct Window *Window;
- register struct NewWindow *NewWindow;
-
- if ( (Window = Pict->Window) != NULL) {
-
- KillCycle();
- FreeScrollTemp(Pict);
-
- Pict->LeftEdge = Window->LeftEdge;
- Pict->TopEdge = Window->TopEdge;
-
- CloseMyWind(Window, Pict->Gadgets );
-
- Pict->Window = NULL;
- Pict->Gadgets = NULL;
- Pict->Flags &= ~LENS_DISPLAYED;
- }
- }
-